#include "functions.h"
#include<stdio.h>
#include<stdlib.h>



//list
Node* add_end(Node *list ,struct info * player_info);
int count(Node* list);
Node* search(Node* list, char *target_name);
Node* sortlist_by_total(Node* list);
Node* sortlist_by_ratio(Node* list);
void load_info(Node * list, int score[], int);
bool read_file(Node *list);
bool save_file(Node *list);
void display_top(Node *list);
void display_all(Node* list);
void display_one(Node *p);
void display_head(void);
void delete_node(Node *list, Node *);
void change(Node *target);
bool display_admin(Node *list, Node **search_temp);
void erase_all(void);


/*整数链表*/
/******按需修改*******/

//游戏结束时进行结算(most important one)
void summarize(Node *list, int score[])
{
    Node *search_temp = NULL;

    printf("GAME OVER!\n");
    if (!read_file(list))//用于读取文件
        printf("Failure: cant init file\n");
    // read into p1
    printf("player 1 plz input your name\n");
    load_info(list, score, 0);
    // read into p2
    printf("player 2 plz input your name\n");
    load_info(list, score, 1);
    system("cls");

    //display mene
    bool flag = true;
    while (flag)
    {
        printf("=======menu=======\n");
        printf("1 List out top 10 play.\n");
        printf("2 Show one's game stastic.\n");
        printf("a Admin mode\n");
        printf("q Quit\n");
        char choice1;
        scanf(" %c", &choice1);
        switch (choice1)
        {
        case 'q':
            {
                flag = false;
                break;
            }
        case '1':
            {
                system("cls");
                display_top(list);
                break;
            }
        case '2':
            {
                system("cls");
                printf("========search pannal=========\n");
                char target[MAX_NAME_LEN];
                printf("input the player name\n");
                scanf("%s", target);
                search_temp = search(list, target);
                if (search_temp == NULL)
                {
                    printf("404 Not Found\n");
                }
                else
                {
                    system("cls");
                    printf("=========resualt of %s==========\n", target);
                    display_head();
                    display_one(search_temp);
                }
                search_temp = NULL;
                break;
            }

        case 'a':
            {
                system("cls");
                printf("=======log in========\n");
                printf("input your password\n");
                printf("input q to quit\n");
                char password[10];
                scanf("%s" ,password);
                if (strncmp(password, "123456", 10) != 0)
                {
                    if (strncmp(password, "q", 10) == 0)
                    {
                        exit(EXIT_SUCCESS);
                    }
                    printf("wrong password\n");
                    break;
                }
                system("cls");

                while (flag)
                {
                    if (!display_admin(list, &search_temp))
                    {
                        break;
                    }
                    char choice2;
                    scanf(" %c", &choice2);
                    switch (choice2)
                    {
                        case 'd':
                        {
                            delete_node(list, search_temp);
                            break;
                        }
                        case 'c':
                        {
                            change(search_temp);
                            break;
                        }
                        case 'q':
                        {
                            flag = false;
                            break;
                        }
                        case 'a':
                        {
                            erase_all();
                        }
                        default:
                        {
                            system("cls");
                            printf("!!!!!!!!Error!!!!!!!!!!");
                            printf("Plz input valid command");
                            printf("\ninput c to continue");
                            char ch;
                            scanf("%c", &ch);
                        }
                    }
                    system("cls");
                }
                break;
            }
        default:
            {
                system("cls");
                printf("!!!!!!!!Error!!!!!!!!!!");
                printf("Plz input valid command");
                printf("\ninput c to continue");
                char ch;
                scanf("%c", &ch);

            }
        }

    }

    //save to file
    if (!save_file(list))
        printf("Failure: cant write the file\n");
}

bool read_file(Node *list)
{
    /* the file format would be like:
     * name\ttotal\twin*/
    FILE *fp;
    //检测是否成功获得文件指针
    fp = fopen(FILENAME, "r");
    if (fp == NULL)
    {
        printf("crearting history file\n");
        fp = fopen(FILENAME, "w");
        if (fp == NULL)
        {
            printf("cant create history file\n");
            fclose(fp);
            return false;
        }
    }
    //读取文件当中的信息（格式为：数据\t数据\t）
    struct info info_temp;
        while (fscanf(fp, "%s\t%d\t%d\t%f", info_temp.name, &(info_temp.total), &(info_temp.win), &(info_temp.ratio)) != EOF)
        {
            add_end(list, &info_temp);
        }
        fclose(fp);
        return true;
}


//返回值代表是否创建成功
bool save_file(Node *list)
{
    FILE *fp;
    fp = fopen(FILENAME, "w");
    if (fp == NULL)
    {
        printf("cant write history file\n");
        return false;
    }
    Node *p = list->next;
    for (;p != NULL;p = p->next)
    {
        fprintf(fp, "%s\t%d\t%d\t%f\n", p->info->name, p->info->total, p->info->win, p->info->ratio);
    }
    return true;
    fclose(fp);
}

//从该局游戏中读取数据
//第二个参数是该局所获得的分数
void load_info(Node * list, int score[], int n)
{
    struct info info_temp;
    char name_temp[MAX_NAME_LEN];
    //name
    scanf(" %s", name_temp);
    strncpy(info_temp.name, name_temp, sizeof(name_temp)/sizeof(char));
    //data
    info_temp.win = score[n];
    info_temp.total = (score[0] + score[1]);
    add_end(list, &info_temp);

}


//add_end()：如果没有相同名字则向链表尾部添加数据
//如果有相同的则更新该人的数据
//需传入 1.链表的头指针 2.添加的数据的值  
Node* add_end(Node *list ,struct info * player_info)
{
    Node *new_node, *p = list;
    new_node=(Node *) malloc(sizeof(Node));
    struct info *s_info = (struct info *)malloc(sizeof(struct info));
    // overflow?
    if(new_node==NULL){
        printf("Error: malloc failed\n");
        exit(EXIT_FAILURE);
    }
    // move to end of list or upd the exsit player data
    if (count(list) > 1)
    {
        p = p->next;
        for (;p->next != NULL; p = p->next)
        {
            if (strcmp(p->info->name, player_info->name) == 0)
            {
                // upd the exist playdata
                p->info->total += player_info->total;
                p->info->win += player_info->win;
                p->info->ratio = (float) p->info->win / p->info->total;
                return p;
            }
        }
        
    }
    // add new player data to end
    printf("Loading: %s\n", player_info->name);
    // load info to struct
    strncpy(s_info->name, player_info->name, MAX_NAME_LEN);
    s_info->win = player_info->win;
    s_info->total = player_info->total;
    new_node->info = s_info;
    new_node->next = p->next;
    new_node->info->ratio = (float) new_node->info->win / new_node->info->total;
    p->next = new_node;
    return new_node;
}

//count():获得链表的结点数
int count(Node* list){
    int number=0;
    for(Node* p=list;p!=NULL;p=p->next)
        ++number;
    return number;
}

//search():传入1.链表的头指针 2.搜索用户名 返回你想要的节点的地址
Node* search(Node* list, char *target_name)
{
    Node* p = list->next;
    for(;p!=NULL ;p=p->next)
    {
        if (strcmp(p->info->name, target_name) == 0)
        {
            return p;
        }
    }
    return p;
}

//sortlist():传入头指针-------本来想自己写，最后一步出了解决不来的灵异事件，遂找了别人的轮子，能跑就行
//按分数排序

//按胜率排序
Node* sortlist_by_ratio(Node* list) 
{
    Node *pfirst=NULL,*pend=NULL;
    pfirst=list;
    float temp;
    while(pfirst->next!=pend)          //外循环
   {
        while(pfirst->next != pend)//内循环
    {
            if(pfirst->info->ratio > pfirst->info->ratio)
            {
                temp=pfirst->info->ratio;  
                pfirst->info->ratio=pfirst->next->info->ratio;
                pfirst->next->info->ratio=temp;
            }
               pfirst=pfirst->next;
        }
        pend=pfirst;//减少最后的已排好的循环
        pfirst=list;
    }
    return list;
}


void display_one(Node *p)
{
        printf("%s\t%d\t%d\t%f\n", p->info->name,p->info->total, p->info->win, p->info->ratio);
}


void display_head(void)
{
    printf("Name\tTotal\tWin\tWin ratio\n");
}

void display_all(Node* list)
{
    Node *p = list->next;
    display_head();
    int num = 0;
    while (p != NULL)
    {
        display_one(p);
        num++;
        p = p->next;
    }
    printf("%d/%d\n", num, count(list));
}

void display_top(Node *list)
{
    Node* p;
    p = list->next;
    sortlist_by_ratio(list);
    printf("===========Best 10===========\n");
    display_head();
    int i = 0;
    for (int j = 0; j < 10 && p != NULL; j++)
    {
        display_one(p);
        p = p->next;
        i++;
    }
    printf("%d/%d\n", i, count(list) - 1);
}

void delete_node(Node *list, Node *target)
{
    Node *p = list;
    for (; p->next != target; p = p->next)
        ;
    p->next = target->next;
    free(target);
    target = NULL;
}

void change(Node *target)
{
    printf("input new name (previous: %s)\n", target->info->name);
    scanf("%s", target->info->name);
    printf("input new total (previous: %d)\n", target->info->total);
    scanf("%d", &target->info->total);
    printf("input new win (previous: %d)\n", target->info->win);
    scanf("%d", &target->info->win);

    target->info->ratio = (float) target->info->win / target->info->total;
    target = NULL;
}

bool display_admin(Node *list, Node **search_temp)
{
    display_all(list);
    printf("+++++++++Adimin++++++++++\n");
    printf("input the name you want to modify\n");
    char temp_name[MAX_NAME_LEN];
    scanf("%s", temp_name);
    *search_temp = search(list, temp_name);
    if (*search_temp == NULL)
    {
        printf("404 Not Found\n");
        return false;
    }
    display_head();
    display_one(*search_temp);

    //modify
    printf("choose your operation\n");
    printf("d to delet\n");
    printf("c to change\n");
    printf("q to quit\n");
    printf("a to delete all\n");

    return true;
}

void erase_all(void)
{
    printf("are you sure you want to erase all player info?\n");
    printf("These date will be delete forever");
    char ch;
    scanf("%c", &ch);
    if (ch == 'y')
    {
        FILE *fp;
        fp = fopen(FILENAME, "w");
        fclose(fp);
        exit(EXIT_SUCCESS);
    }
}
